package com.youlu.campus.service.wechat.impl;

import com.youlu.campus.base.exception.BusinessException;

import com.youlu.campus.entity.*;
import com.youlu.campus.entity.VO.req.WechatH5CodeReqVO;
import com.youlu.campus.entity.VO.res.UserResponse;
import com.youlu.campus.entity.domain.WechatAccessToken;

import com.youlu.campus.entity.domain.WechatSiteUserInfoDomain;

import com.youlu.campus.service.cache.CacheActivityService;
import com.youlu.campus.service.platform.PlatformConfigService;
import com.youlu.campus.service.utils.WebTokenUtils;
import com.youlu.campus.service.wechat.WechatConfigInfoService;
import com.youlu.campus.service.wechat.WechatH5Service;
import com.youlu.campus.service.wechat.WechatService;
import com.youlu.campus.service.wechat.WechatThirdUserService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.net.URLEncoder;
import java.util.Date;
import java.util.Objects;

@Slf4j
@Service
public class WechatThirdUserServiceImpl implements WechatThirdUserService {
    @Autowired
    private MongoTemplate mongoTemplate;
    @Autowired
    private RedisTemplate<String, String> redisTemplate;
    @Autowired
    private WechatConfigInfoService wechatConfigInfoService;
    @Autowired
    private WechatService wechatService;
    @Autowired
    private WechatH5Service wechatH5Service;
    @Autowired
    private CacheActivityService cacheActivityService;
    @Autowired
    private PlatformConfigService platformConfigService;

    @Override
    public WechatThirdUserPO findByOpenId(String appId, String openId) {
        Query query = new Query().addCriteria(Criteria.where("openId").is(openId).and("appId").is(appId));
        WechatThirdUserPO wechatThirdUserPO = mongoTemplate.findOne(query, WechatThirdUserPO.class);
        return wechatThirdUserPO;
    }

    @Override
    public WechatThirdUserPO findByUnionId(String unionId) {
        Query query = new Query().addCriteria(Criteria.where("unionId").is(unionId));
        WechatThirdUserPO wechatThirdUserPO = mongoTemplate.findOne(query, WechatThirdUserPO.class);
        return wechatThirdUserPO;
    }

    @Override
    public void create(WechatThirdUserPO wechatThirdUserPO) {

    }

    @Override
    public UserResponse login(String appId, String code) {
        log.info(":>>> 微信第三方用户登录开始 app id {},code:{} ", appId, code);
        if (StringUtils.isBlank(appId) || StringUtils.isBlank(code)) {
            log.error(":>>> 微信第三方登陆参数错误");
            throw new BusinessException("微信第三方登陆参数错误");
        }
        WechatConfigInfo configInfo = wechatConfigInfoService.find(appId);
        if (Objects.isNull(configInfo) || StringUtils.isBlank(configInfo.getAppSecret())) {
            log.error(":>>> 微信小程序登陆参数错误:appId:{}", appId);
            throw new BusinessException("微信小程序登陆参数错误");
        }
        WechatAccessToken accessToken = wechatService.getAccessToken(appId, code);
        final String openId = accessToken.getOpenId();
        WechatSiteUserInfoDomain userInfo = wechatService.getUserInfo(appId, openId);
        WechatH5UserPO wechatH5UserPO = wechatH5Service.findByUnionId(userInfo.getUnionId());
        log.info(":>>> 相同unionId:{} 的微信用户:{}", userInfo.getUnionId(), wechatH5UserPO == null ? null : wechatH5UserPO.getId());
        String accountInfoId = "";
        if (Objects.isNull(wechatH5UserPO)) {
            UserPO userPO = new UserPO();
            userPO.setAppId(appId);
            userPO.setOpenId(openId);
            userPO.setUnionId(userInfo.getUnionId());
            userPO.setCreatedTime(new Date());
            userPO.setId(null);
            userPO = mongoTemplate.insert(userPO);
            accountInfoId = userPO.getId();
        } else {
            accountInfoId = wechatH5UserPO.getAccountInfoId();
        }
        WechatThirdUserPO thirdUserPO = this.findByOpenId(appId, accessToken.getOpenId());
        if (Objects.isNull(thirdUserPO)) {
            log.error(":>>> 微信三方登陆:{} 用户不存在新增用户");
            //保存到数据库
            thirdUserPO = new WechatThirdUserPO();
            thirdUserPO.setAppId(appId);
            thirdUserPO.setOpenId(openId);
            thirdUserPO.setUnionId(userInfo.getUnionId());
            thirdUserPO.setId(null);
            thirdUserPO.setCreatedTime(new Date());
            thirdUserPO.setAccountInfoId(accountInfoId);
            thirdUserPO.setAvatarUrl(userInfo.getAvatarUrl());
            thirdUserPO.setProvince(userInfo.getProvince());
            thirdUserPO.setCity(userInfo.getCity());
            thirdUserPO.setCountry(userInfo.getCountry());
            thirdUserPO.setAuthorized(true);
            if (Objects.nonNull(userInfo.getSex())) {
                switch (userInfo.getSex()) {
                    case 1:
                        thirdUserPO.setGender("男");
                        break;
                    case 2:
                        thirdUserPO.setGender("女");
                        break;
                }
            }
            mongoTemplate.insert(thirdUserPO);
            log.info(":>>> 微信三方授权用户:{},不存在,新建", thirdUserPO.getOpenId());
            UserResponse userResponse = new UserResponse();
            userResponse.setOpenId(openId);
            userResponse.setToken(WebTokenUtils.signToken(openId));
            userResponse.setAuthorized(false);
            return userResponse;
        }
        UserResponse userResponse = new UserResponse();
        userResponse.setOpenId(openId);
        userResponse.setToken(WebTokenUtils.signToken(openId));
        userResponse.setAuthorized(true);
        return userResponse;
    }

    @Override
    public String getwechatThirdLoginCode(WechatH5CodeReqVO req) {
        log.info(":>>> 开始获取微信三方授权 Code链接, scope - > {}", req.getScope());
        ActivityInfo activityInfo = cacheActivityService.findById(req.getActivityId());
        if (Objects.isNull(activityInfo) || StringUtils.isBlank(activityInfo.getThemeColor())) {
            log.error(":>>> 活动:{} 不存在,或颜色配置:{}", req.getActivityId(), activityInfo.getThemeColor());
            throw new BusinessException("活动不存在,或颜色配置错误");
        }
        String scope = req.getScope();
        if (StringUtils.isBlank(scope)) {
            scope = "snsapi_login";
        }
        Integer rewardType = req.getRewardType();
        String redirect_uri = "";
        try {
            redirect_uri =
                    URLEncoder.encode(platformConfigService.getBizFrontDomain() + "/h5/#/pages/user-login?activityId=" + req.getActivityId() + "&appId=" + req.getAppId() + "&type=" + req.getType() + "&theme=" + activityInfo.getThemeColor() + "&scope=" + scope + "&rewardType=" + rewardType, "UTF-8");
            log.info("appId - > {} scope - >{} redirect_uri - >{}", req.getAppId(), scope, redirect_uri);
            String url = "https://open.weixin.qq.com/connect/qrconnect?appid=" + req.getAppId() + "&redirect_uri=" + redirect_uri + "&response_type=code&scope=" + scope + "&state=STATE#wechat_redirect";
            log.info(":>>> 返回的地址为:{}", url);
            return url;
        } catch (Exception e) {
            log.error(":>>> 获取解码错误:{}", e);
            return "";
        }
    }
}
